import Foundation

class GameViewModel: ObservableObject {
    @Published private var gameBoard: GameBoard
    @Published var showAlert = false
    @Published var flaggedCount: Int = 0 {
        didSet {
            // 避免在属性观察器中修改自身，防止递归
            if oldValue != flaggedCount {
                // 只统计标记的数量，不管是否正确
                let flags = gameBoard.cells.flatMap { $0 }
                    .filter { $0.state == .flagged }.count
                if flags != flaggedCount {
                    DispatchQueue.main.async {
                        self.flaggedCount = flags
                    }
                }
            }
        }
    }
    @Published var lastFlaggedCoordinate: Coordinate? = nil
    @Published var currentDifficulty: DifficultyLevel
    
    var currentConfig: GameConfig {
        currentDifficulty.config
    }
    
    init() {
        // 先初始化所有存储属性
        self.currentDifficulty = .beginner
        self.showAlert = false
        self.flaggedCount = 0
        self.lastFlaggedCoordinate = nil
        self.gameBoard = GameBoard(difficulty: .beginner)
    }
    
    var currentGameState: GameState {
        gameBoard.gameState
    }
    
    var boardCells: [[Cell]] {
        gameBoard.cells
    }
    
    // 需要同步修改 GameBoard 的 cells 访问权限
    
    func newGame() {
        // 先停止计时器
        stopTimer()
        
        // 重置所有状态
        gameBoard = GameBoard(difficulty: currentDifficulty)
        flaggedCount = 0
        lastFlaggedCoordinate = nil
        isFirstClick = true
        elapsedSeconds = 0
        startTime = nil
        showAlert = false
        
        // 通知视图更新
        objectWillChange.send()
    }
    
    // 计时器状态
    private var startTime: Date?
    @Published var elapsedSeconds = 0
    private var timer: Timer?
    
    private var isFirstClick = true
    
    func revealCell(at position: Coordinate) {
        guard gameBoard.gameState == .playing else { return }
        startTimerIfNeeded()
        
        // 首次点击保证安全区域
        if isFirstClick {
            regenerateSafeBoard(startingAt: position)
            isFirstClick = false
        }
        
        gameBoard.reveal(at: position)
        
        // 检查是否触发地雷
        if gameBoard.cells[position.x][position.y].isMine {
            gameBoard.gameState = .lost(reason: .steppedOnMine)
            showAlert = true
        } else {
            showAlert = gameBoard.gameState != .playing
        }
        
        // 自动展开周围安全区域
        if case .revealed = gameBoard.cells[position.x][position.y].state,
           gameBoard.cells[position.x][position.y].neighborMines == 0 {
            gameBoard.floodReveal(from: position)
        }
    }
    
    func toggleFlag(at position: Coordinate) {
        guard gameBoard.gameState == .playing else { return }
        
        // 记录最后标记的位置
        lastFlaggedCoordinate = position
        
        // 切换标记状态
        gameBoard.toggleFlag(at: position)
        
        // 更新标记计数（让属性观察器处理）
        objectWillChange.send()
        
        // 检查胜利条件
        let totalMines = currentConfig.mines
        let correctFlags = gameBoard.cells.flatMap { $0 }
            .filter { $0.isMine && $0.state == .flagged }.count
        let wrongFlags = gameBoard.cells.flatMap { $0 }
            .filter { !$0.isMine && $0.state == .flagged }.count
        
        // 胜利条件：正确标记数等于总雷数且没有错误标记
        if correctFlags == totalMines && wrongFlags == 0 {
            gameBoard.gameState = .won
            showAlert = true
        }
    }
    
    private func regenerateSafeBoard(startingAt position: Coordinate) {
        repeat {
            gameBoard = GameBoard(difficulty: currentDifficulty)
        } while gameBoard.cells[position.x][position.y].isMine || 
               gameBoard.cells[position.x][position.y].neighborMines != 0
        
        // 不需要重置计时器，因为这是第一次点击时的操作
        // 计时器会在 revealCell 中的 startTimerIfNeeded 启动
        isFirstClick = false
    }
    
    // MARK: - 计时器管理
    private func startTimerIfNeeded() {
        guard timer == nil else { return }
        startTime = Date()
        
        // 在主线程上创建和启动计时器
        DispatchQueue.main.async {
            self.timer = Timer.scheduledTimer(withTimeInterval: 1.0, repeats: true) { [weak self] _ in
                guard let self = self, let start = self.startTime else { return }
                self.elapsedSeconds = Int(Date().timeIntervalSince(start))
                
                // 处理最大时间限制（需求1.3.4）
                if self.elapsedSeconds >= 999 {
                    self.stopTimer()
                    self.gameBoard.gameState = .lost(reason: .timeExpired)
                    self.showAlert = true
                }
            }
            
            // 确保计时器在主运行循环中运行
            RunLoop.main.add(self.timer!, forMode: .common)
        }
    }
    
    private func stopTimer() {
        timer?.invalidate()
        timer = nil
    }
    
    // 添加难度切换功能
    func changeDifficulty(difficulty: DifficultyLevel) {
        currentDifficulty = difficulty
        newGame()
    }
}
